/**
 Bins.h

 \file
 Declaration of class Bins.

 \author Thomas Burton 
 \date 3/2/12
 \copyright 2012 BNL. All rights reserved.
*/

#ifndef _Bins_H_
#define _Bins_H_

#include <vector>

#include <Rtypes.h>
#include <TAxis.h>

namespace tppmc {

   /**
    A collection of "bins" in a continuous range.
    \todo Add Minima() and Maxima() methods - those would be handy!
   */
   class Bins {

   public:

      /** Destructor */
      virtual ~Bins() { }

      /**
       The number of intervals.
      */
      virtual int Number() const = 0;

      /**
       Returns (Number() + 1) values defining the interval edges.
      */
      virtual std::vector<double> Edges() const = 0;

      /**
       Returns Number() values defining the interval centres.
      */
      virtual std::vector<double> Centres() const = 0;

      /**
       Returns Number() pairs with the minimum and maximum of each bin.
      */
      virtual std::vector<std::pair<double, double> > MinMax() const = 0;

      ClassDef(tppmc::Bins, 1)
   };


   class UniformBins : public Bins {

   public:

      UniformBins();

      UniformBins(int n, double min, double max);

      virtual ~UniformBins() { }

      /**
       The number of intervals.
       */
      virtual int Number() const;
      
      /**
       Returns (Number() + 1) values defining the interval edges.
       */
      virtual std::vector<double> Edges() const;

      /**
       Returns Number() values defining the interval centres.
       */
      virtual std::vector<double> Centres() const;

      /**
       Returns Number() pairs with the minimum and maximum of each bin.
       */
      virtual std::vector<std::pair<double, double> > MinMax() const;

   protected:

      TAxis mBins;

      ClassDef(tppmc::UniformBins, 1)
   };


   /**
    Bins with equal intervals in log_10(x)
   */
   class Log10Bins : public Bins {
      
   public:
      
      Log10Bins();
      
      Log10Bins(int n, double min, double max);
      
      virtual ~Log10Bins() { }
      
      /**
       The number of intervals.
       */
      virtual int Number() const;
      
      /**
       Returns (Number() + 1) values defining the interval edges.
       */
      virtual std::vector<double> Edges() const;
      
      /**
       Returns Number() values defining the interval centres.
       Centres are defined as the logarithmic centre, i.e.
       0.5 * (log10(low) + log10(high)), not 0.5(low + high).
       */
      virtual std::vector<double> Centres() const;
      
      /**
       Returns Number() pairs with the minimum and maximum of each bin.
       */
      virtual std::vector<std::pair<double, double> > MinMax() const;
      
   protected:
      
      TAxis mBins;
      
      ClassDef(tppmc::Log10Bins, 1)
   };
   
} // namespace tppmc

#endif
